package com.itmuch.box.controller.common;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.itmuch.box.controller.common.ueditor.ConfigItem;
import com.itmuch.box.controller.common.ueditor.UeditorConfig;
import com.itmuch.box.controller.common.ueditor.UeditorUploadState;
import com.itmuch.box.core.base.BaseController;
import com.itmuch.box.core.constant.ConstantConfig;
import com.itmuch.box.core.security.SubjectUtil;
import com.itmuch.box.domain.attach.entity.Attach;
import com.itmuch.box.service.attach.AttachService;
import com.itmuch.box.service.config.ConfigService;

/**
 * ueditor 上传控制器
 * @author 周立
 * @see http://blog.csdn.net/sunhuwh/article/details/45122085
 */
@Controller
@RequestMapping("${commonPath}/ueditor")
public class UeditorController extends BaseController {
    @Resource
    private AttachService attachService;
    @Resource
    private ConfigService configService;

    @RequestMapping(value = "/upload", method = RequestMethod.GET)
    @ResponseBody
    public String upload(String action) throws IOException {
        if ("config".equals(action)) {

            //            URL url = UeditorController.class.getClassLoader().getResource("config.json");
            //
            //            String string = FileUtils.readFileToString(new File(url.getPath()));
            return UeditorConfig.getConfigString();
        }
        return null;
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public UeditorUploadState upload(HttpServletRequest request, String action, @RequestParam MultipartFile upfile) {
        String originalFilename = upfile.getOriginalFilename();
        String extension = FilenameUtils.getExtension(originalFilename);
        long size = upfile.getSize();

        ConfigItem configItem = UeditorConfig.getConfigItems();

        int maxSize = 0;
        List<String> allowedFiles = null;
        switch (action) {
        // 上传图片
        case "uploadimage":
            maxSize = configItem.getImageMaxSize();
            allowedFiles = configItem.getImageAllowFiles();
            break;
        // 上传视频
        case "uploadvideo":
            maxSize = configItem.getVideoMaxSize();
            allowedFiles = configItem.getVideoAllowFiles();
            break;
        // 上传文件
        case "uploadfile":
            maxSize = configItem.getFileMaxSize();
            allowedFiles = configItem.getFileAllowFiles();
            break;
        }

        UeditorUploadState state = new UeditorUploadState();
        if (size == 0) {
            state.setState(UeditorUploadState.NOTFOUND_UPLOAD_DATA);
            return state;
        } else if (size > maxSize) {
            state.setState(UeditorUploadState.MAX_SIZE);
            return state;
        }
        if (!allowedFiles.contains("." + extension.toLowerCase())) {
            state.setState(UeditorUploadState.NOT_ALLOW_FILE_TYPE);
            return state;
        }

        try {
            Attach attach = this.uploadFile(request, upfile);

            String attachDomain = this.configService.selectValueByKey(ConstantConfig.ATTACH_DOMAIN);
            String url = String.format("%s/%s", attachDomain, attach.getPath());

            state.setUrl(url);
            state.setSize(String.valueOf(size));
            state.setType("." + extension);
            state.setState(UeditorUploadState.SUCCESS);
            state.setOriginal(originalFilename);
            return state;
        } catch (IOException e) {
            state.setState(UeditorUploadState.IO_ERROR);
            return state;
        }
    }

    private Attach uploadFile(HttpServletRequest request, MultipartFile file) throws IOException {
        String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
        Integer memberId = SubjectUtil.getSubjectId();
        String originalFilename = file.getOriginalFilename();
        String extension = FilenameUtils.getExtension(originalFilename);

        // 保存的文件名 UUID.后缀
        String uuid = UUID.randomUUID().toString();
        String savedFilename = uuid + "." + extension;

        // 相对于attach.domain的路径
        String dirInAttachDomain = String.format("%s/%s/%s/%s", this.uploadPath, this.projectCode, memberId, dateStr);
        // 相对attach.domain的url
        String urlInAttachDomain = String.format("%s/%s", dirInAttachDomain, savedFilename);

        // 文件所在目录在磁盘里的全路径
        String dirInDisk = String.format("%s/%s", this.attachLocation, dirInAttachDomain);
        File dirPath = new File(dirInDisk);
        if (!dirPath.exists()) {
            dirPath.mkdirs();
        }

        // 文件在磁盘中的全路径
        File fileToWrite = new File(String.format("%s/%s", dirInDisk, savedFilename));

        byte[] bytes = file.getBytes();
        FileCopyUtils.copy(bytes, fileToWrite);

        Attach attach = new Attach();
        attach.setMemberId(memberId);
        attach.setOriginalFilename(originalFilename);
        attach.setPath(urlInAttachDomain);
        attach.setUuid(uuid);

        this.attachService.insert(attach);
        return attach;
    }

}
